
#include <BSonDocument>
#include <BXmlDocument>
#include <BFile>
#include <BMenuBar>
#include <BHBoxLayout>
#include <BVBoxLayout>
#include <BGridLayout>
#include <BStackLayout>

#include "MainWindow.h"

MainWindow::MainWindow()
{
	BMenuBar* menuBar = new BMenuBar();
	menuBar->setSpacing(2);
	{
		BMenu* fileMenu = new BMenu("file");
		BAction* newAction = fileMenu->addAction("New");
		BAction* openAction = fileMenu->addAction("Open");
		BAction* saveAction = fileMenu->addAction("Save");
		BAction* resetAction = fileMenu->addAction("Reset");

		BMenu* widgetMenu = new BMenu("Widget");
		{
			widgetMenu->addAction("Dialog");
			widgetMenu->addAction("Label");
			widgetMenu->addAction("Button");
			widgetMenu->addAction("SpinBox");
		}
		BMenu* layoutMenu = new BMenu("Layout");
		{
			layoutMenu->addAction("Layout");
			layoutMenu->addAction("StackLayout");
			layoutMenu->addAction("HBoxLayout");
			layoutMenu->addAction("VBoxLayout");
			layoutMenu->addAction("GridLayout");
		}

		menuBar->addMenu(fileMenu);
		menuBar->addMenu(widgetMenu);
		menuBar->addMenu(layoutMenu);

		connect(openAction, Signal_Triggered, &MainWindow::slotOpenActionTrigger);
		connect(saveAction, Signal_Triggered, &MainWindow::slotSaveActionTrigger);
		connect(resetAction, Signal_Triggered, &MainWindow::slotResetActionTrigger);
		connect(widgetMenu, Signal_Triggered, &MainWindow::slotInsertWidgetMenuTrigger);
		connect(layoutMenu, Signal_Triggered, &MainWindow::slotInsertLayoutMenuTrigger);
	}

	BHBoxLayout* toolsLayout = new BHBoxLayout();
	{
		_eventEnabledCheckBox = new BCheckBox("event-enabled");
		toolsLayout->addWidget(_eventEnabledCheckBox);
	}

	BHBoxLayout* buttonLayout = new BHBoxLayout();
	buttonLayout->setSizePolicy(Policy_Preferred);
	{
		BLabel* documentLabel = new BLabel("Document");

		_imageSizeComboBox = new BComboBox();
		_imageSizeComboBox->addItem("20*20", 20);
		_imageSizeComboBox->addItem("40*40", 40);
		_imageSizeComboBox->addItem("80*80", 80);

		buttonLayout->addWidget(documentLabel);
		buttonLayout->addSpring();
		buttonLayout->addWidget(_imageSizeComboBox);
	}

	_treeWidget = new BTreeWidget();
	_treeWidget->setScrollPolicy(ScrollPolicy_Never);
	_treeWidget->setStyleSheet("item-color-hovered:empty");
	_treeWidget->setHorizontalScrollPolicy(ScrollPolicy_Never);
	_treeWidget->setSelectMode(Select_Rows | Select_Multiple);
	_treeWidget->setLayout(buttonLayout, Part_Top);
	_treeWidget->setIconSize(36);

	_pixmapArea = new PixmapArea();

	_propertyBoard = new PropertyBoard();
	_propertyBoard->setWidthPolicy(Policy_Dynamic);

	BHBoxLayout* splitLayout = new BHBoxLayout();
	splitLayout->setSplitable(true);
	splitLayout->setSpacing(6);
	splitLayout->addWidget(_treeWidget, 1);
	splitLayout->addWidget(_pixmapArea, 10);
	splitLayout->addWidget(_propertyBoard);

	BVBoxLayout* layout = new BVBoxLayout(this);
	layout->addWidget(menuBar);
	layout->addLayout(toolsLayout);
	layout->addLayout(splitLayout, 1000);

	connect(_eventEnabledCheckBox, Signal_Checked, &MainWindow::slotEventEnabledChecked);

	connect(_treeWidget, Signal_ItemSelected, &MainWindow::slotTreeItemSelected);

	connect(_pixmapArea, "selected", &MainWindow::slotObjectSelected);
	connect(_pixmapArea, "unselected", &MainWindow::slotObjectUnselected);
	connect("order-adjusted", &MainWindow::slotObjectOrderAdjusted);

	_pixmapArea->pixmap()->setSize(800, 600);
}

void MainWindow::insertWidget(BWidget* widget)
{
	BTreeItem* item = new BTreeItem(widget->name());
	if (BTreeItem* parentItem = _treeWidget->selectedItem())
	{
		BWidget* parent = parentItem->asset();
		parent->addChild(widget);
		parentItem->addChild(item);
		parentItem->setExpanded(true);
	}
	else
	{
		BPixmap* pixmap = _pixmapArea->pixmap();
		pixmap->addWidget(widget);
		_treeWidget->addTopItem(item);

		BRect view = _pixmapArea->area() & _pixmapArea->centerRect();
		view = view - _pixmapArea->area().pos();
		BRect rect = view.align(Align_Center, widget->size());
		widget->setRect(rect);

	}
	item->setAsset(widget);
	BImage* image = new BImage(Format_RGBA);
	item->setImage(image);
	connect(widget, Signal_Frame, &MainWindow::slotWidgetFrame);

	_pixmapArea->select(widget);
}

BXmlNode* MainWindow::writeXmlNode(BWidget* widget)
{
	return 0;
}
BWidget* MainWindow::readXmlNode(BXmlNode* node)
{
	return 0;
}

void MainWindow::slotOpenActionTrigger(BObject* object, const BValue& value)
{
	BString fileName = BFileDialog::OpenFile(this, "Open UI File", "xml,uix,son,uis,obc,ui");
	BWidget* widget = ReadFile<BWidget>(fileName);
	if (widget)
	{
		BPixmap* pixmap = _pixmapArea->pixmap();
		pixmap->setSize(widget->size());	
		insertWidget(widget);
	}
}
void MainWindow::slotSaveActionTrigger(BObject* object, const BValue& value)
{
	BString fileName = BFileDialog::SaveFile(this, "Save Image File");
	if (fileName.size())
	{
		BPixmap* pixmap = _pixmapArea->pixmap();
		if (0 == strcmp(fileName.ext(), "son") || 0 == strcmp(fileName.ext(), "uis"))
		{
			BReadWrite* rw = FindReadWrite("osc");
			rw->save(fileName, pixmap);
			return;
		}
		if (0 == strcmp(fileName.ext(), "xml") || 0 == strcmp(fileName.ext(), "uix"))
		{
			BFile file(fileName);
			if (file.open(IO_WriteText))
			{
				BXmlDocument doc;
				BXmlNode* root = new BXmlNode(fileName.ext());
				for (int i = 0; i < pixmap->widgetCount(); i++)
				{
					BWidget* widget = pixmap->widget(i);
					BXmlNode* widgetNode = writeXmlNode(widget);
					root->addChild(widgetNode);
				}
				doc.write(file, root);
			}
			return;
		}
		if (0 == strcmp(fileName.ext(), "obc") || 0 == strcmp(fileName.ext(), "ui"))
		{
			BReadWrite* rw = FindReadWrite("obc");
			rw->save(fileName, pixmap);
			return;
		}
	}
}
void MainWindow::slotResetActionTrigger(BObject* object, const BValue& value)
{
	_pixmapArea->clearSelection();
	_pixmapArea->pixmap()->clearWidgets();
	_treeWidget->clearItems();
}
void MainWindow::slotInsertWidgetMenuTrigger(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (action)
	{
		BWidget* widget = 0;
		if (action->text() == "Dialog")
		{
			widget = new BDialog("dialog");
			widget->setName("dialog");
			widget->setVisible(true);
		}
		else if (action->text() == "Label")
		{
			widget = new BLabel("label");
			widget->setName("label");
		}
		else if (action->text() == "Button")
		{
			widget = new BButton("button");
			widget->setName("button");
		}
		else if (action->text() == "SpinBox")
		{
			widget = new BSpinBox();
			widget->setName("SpinBox");
		}
		if (widget)
		{
			insertWidget(widget);
		}
	}
}
void MainWindow::slotInsertLayoutMenuTrigger(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (action)
	{
		BLayout* layout = 0;
		if (action->text() == "Layout")
		{
			layout = new BLayout("Layout");
		}
		else if (action->text() == "StackLayout")
		{
			layout = new BStackLayout("StackLayout");
		}
		else if (action->text() == "HBoxLayout")
		{
			layout = new BHBoxLayout("HBoxLayout");
		}
		else if (action->text() == "VBoxLayout")
		{
			layout = new BVBoxLayout("VBoxLayout");
		}
		else if (action->text() == "GridLayout")
		{
			layout = new BGridLayout("GridLayout");
		}
		layout->setRect(100, 100);
		BTreeItem* item = new BTreeItem(layout->name());
		if (BTreeItem* parentItem = _treeWidget->selectedItem())
		{
			BWidget* parent = parentItem->asset();
			parent->addLayout(layout);
			parentItem->addChild(item);
			parentItem->setExpanded(true);
			item->setAsset(layout);
			BImage* image = new BImage(Format_RGBA);
			item->setImage(image);
		}
	}
}
void MainWindow::slotEventEnabledChecked()
{
	if (_eventEnabledCheckBox->checked())
		_pixmapArea->enableEvent();
	else
		_pixmapArea->disableEvent();
}

void MainWindow::slotTreeItemSelected(BObject* object, const BValue& value)
{
	BTreeItem* item = value;
	if (item->isSelected())
		_pixmapArea->select(item->asset());
	else
		_pixmapArea->unselect(item->asset());
}
void MainWindow::slotObjectSelected(BObject* object, const BValue& value)
{
	BTreeItem* item = _treeWidget->itemOfAsset(value);
	_treeWidget->setItemSelected(item, true);
	_propertyBoard->setAsset(value);
}
void MainWindow::slotObjectUnselected(BObject* object, const BValue& value)
{
	BTreeItem* item = _treeWidget->itemOfAsset(value);
	_treeWidget->setItemSelected(item, false);
	if (_propertyBoard->asset() == value)
	{
		_propertyBoard->setAsset(BValue());
	}
}
void MainWindow::slotObjectOrderAdjusted(BObject* object, const BValue& value)
{
	BWidget* widget = value;
	BPixmap* pixmap = _pixmapArea->pixmap();
	pixmap->clearWidgets();
	BTreeItem* item = _treeWidget->itemOfAsset(value);
	item->parent()->insertChild(widget->index(), item);
}

void MainWindow::slotWidgetFrame(BObject* object, const BValue& value)
{
	BWidget* widget = (BWidget*)object;
	BTreeItem* item = _treeWidget->itemOfAsset(object);
	BImage* image = item->image();
	widget->capture(image);
	image->reverse(Orientation_Vertical);
	_treeWidget->fresh();
}

void MainWindow::updateEvent(const BEvent& event)
{

}
